package com.mcxx.modules.minimumliving.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.mcxx.common.exception.BizException;
import com.mcxx.constant.MQConstant;
import com.mcxx.modules.minimumliving.service.CustomFundPayService;
import com.mcxx.modules.base.utils.QueryParamUtil;
import com.mcxx.modules.base.utils.excel.ImportExcel;
import com.mcxx.modules.filemanage.easypoi.util.ExportExcelService;
import com.mcxx.modules.filemanage.file.service.FileService;
import com.mcxx.modules.miniSalvation.family.dto.CustomFundDTO;
import com.mcxx.modules.miniSalvation.family.param.SalvationObjectParam;
import com.mcxx.modules.miniSalvation.fundpay.dto.CustomFundPayDTO;
import com.mcxx.modules.miniSalvation.fundpay.dto.CustomFundPayMemberDTO;
import com.mcxx.modules.miniSalvation.fundpay.entity.CustomFundPayMemberEntity;
import com.mcxx.modules.miniSalvation.fundpay.param.CustomFundPayMemberParam;
import com.mcxx.modules.miniSalvation.fundpay.service.read.CustomFundPayMemberReadService;
import com.mcxx.modules.miniSalvation.fundpay.service.read.CustomFundPayReadService;
import com.mcxx.modules.miniSalvation.fundpay.service.write.CustomFundPayMemberWriteService;
import com.mcxx.modules.miniSalvation.fundpay.service.write.CustomFundPayWriteService;
import com.mcxx.modules.miniSalvation.order.service.read.OrderReadService;
import com.mcxx.modules.miniSalvation.salary.service.write.FamilySalaryWriteService;
import com.mcxx.modules.system.dto.MQMessageDTO;
import com.mcxx.modules.system.entity.TaskExportEntity;
import com.mcxx.modules.system.service.write.TaskExportWriteService;
import com.mcxx.util.Constant;
import com.yinhai.ta404.component.audit.vo.ExcelInfo;
import com.yinhai.ta404.core.restservice.requestbean.PageParam;
import com.yinhai.ta404.core.restservice.resultbean.Page;
import com.yinhai.ta404.core.security.vo.UserAccountVo;
import com.yinhai.ta404.core.service.BaseService;
import com.yinhai.ta404.core.transaction.annotation.TaTransactional;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.*;
import java.util.stream.Collectors;


@Slf4j
@Service
@TaTransactional
public class CustomFundPayServiceImpl extends BaseService implements CustomFundPayService {

    @Autowired
    private CustomFundPayReadService customFundPayReadService;
    @Autowired
    private CustomFundPayWriteService customFundPayWriteService;
    @Autowired
    private CustomFundPayMemberReadService customFundPayMemberReadService;
    @Autowired
    private CustomFundPayMemberWriteService customFundPayMemberWriteService;
    @Autowired
    private FamilySalaryWriteService familySalaryWriteService;
    @Autowired
    private OrderReadService orderReadService;
    @Autowired
    private RabbitTemplate rabbitTemplate;
    @Autowired
    private ExportExcelService exportExcelService;
    @Autowired
    private FileService fileService;
    @Autowired
    private TaskExportWriteService taskExportWriteService;



    @Override
    public Map<String, List<String>> delCustomFundPay(List<String> customFundPayIdList) {

        List<String> stateList = new ArrayList<String>(){{add(Constant.FundPayState.CREATE); add(Constant.FundPayState.REVOKE);}};
        Map<String, List<String>> rstMap = customFundPayReadService.getIdByIdAndStates(customFundPayIdList, stateList);
        if(rstMap.containsKey("success") == false){

            return rstMap;
        }


        int rst = customFundPayWriteService.delCustomFundPay(rstMap.get("success"));


        if(rst <= 0){

            rstMap.put("fail", customFundPayIdList);
            rstMap.remove("success");
        }

        return rstMap;
    }


    @Override
    public Map<String, List<String>> confirmCustomFundPay(List<String> customFundPayIdList, UserAccountVo userAccountVo) {

        List<String> stateList = new ArrayList<String>(){{add( Constant.FundPayState.CREATE); add( Constant.FundPayState.REVOKE);}};
        Map<String, List<String>> rstMap = customFundPayReadService.getIdByIdAndStates(customFundPayIdList, stateList);
        if(rstMap.containsKey("success") == false){

            return rstMap;
        }



        Map<String, List<String>> cntMemberMap = customFundPayReadService.getIdByIdAndMemberNum(rstMap.get("success"));

        if(cntMemberMap.containsKey("success") == false){

            rstMap.put("fail", customFundPayIdList);
            rstMap.remove("success");
            return rstMap;
        }
        if(cntMemberMap.containsKey("fail") == true){
            List<String> a = cntMemberMap.get("fail");
            rstMap.get("fail").addAll(a);
            rstMap.put("success", cntMemberMap.get("success"));
        }



        int rst = customFundPayWriteService.updateStateByIds(cntMemberMap.get("success"), Constant.FundPayState.CONFIRM);


        if(rst <= 0){

            rstMap.put("fail", customFundPayIdList);
            rstMap.remove("success");
        }


        return rstMap;
    }


    @Override
    public Map<String, List<String>> cancelCustomFundPay(List<String> fundPayIdList) {

        Map<String, List<String>> rstMap = customFundPayReadService.getIdByIdAndState(fundPayIdList, Constant.FundPayState.CONFIRM);
        if(rstMap.containsKey("success") == false){

            return rstMap;
        }


        familySalaryWriteService.deleteByCustomFundPayId(fundPayIdList);


        int rst = customFundPayWriteService.updateStateByIds(rstMap.get("success"), Constant.FundPayState.REVOKE);
        if(rst <= 0){

            rstMap.put("fail", fundPayIdList);
            rstMap.remove("success");
        }

        return rstMap;
    }


    @Override
    public void addCustomFundPayObjects(String customFundPayId, List<String> memberIdList, UserAccountVo userAccountVo) {

        CustomFundPayDTO customFundPayDTO = customFundPayReadService.getById(customFundPayId);


        List<CustomFundPayMemberEntity> customFundPayMemberList = customFundPayMemberReadService.getCustomMemberListByMemberId(customFundPayDTO, memberIdList, userAccountVo);


        customFundPayMemberWriteService.inserts(customFundPayMemberList, customFundPayId);


        customFundPayWriteService.updateAddMemberNum(customFundPayId, customFundPayMemberList.size());
    }

    @Override
    public String importCustomFundPayObjects(String customFundPayId, MultipartFile file, UserAccountVo userAccountVo){

        Map<String, CustomFundPayMemberDTO> excelMemberMap = ImportExcel.CustomFundPayImportExcel(file);


        CustomFundPayDTO customFundPayDTO = customFundPayReadService.getById(customFundPayId);
        if(null == customFundPayDTO){
            throw new BizException("-1", "名册异常，无法导入数据");
        }



        List<String> idcardList = new ArrayList<>(excelMemberMap.keySet());

        List<CustomFundPayMemberEntity> canAddMemberList = customFundPayMemberReadService.getCustomMemberListByIdcard(customFundPayDTO, idcardList, userAccountVo);
        if(canAddMemberList.size() == 0){
            throw new BizException("-1", "没有可以导入到本次补发名册的成员");
        }


        int rst = customFundPayMemberWriteService.insertsExcel(canAddMemberList, excelMemberMap, customFundPayId);
        if(rst <= 0){
            throw new BizException("-1", "成员添加失败,数据库操作异常");
        }


        rst = customFundPayWriteService.updateAddMemberNum(customFundPayId, canAddMemberList.size());
        if(rst <= 0){
            throw new BizException("-1", "名册信息更新失败,数据库操作异常");
        }


        return packageRstMsg(excelMemberMap, canAddMemberList);
    }


    @Override
    public int delCustomFundPayObjects(String customFundPayId, List<String> memberIdList) {

        int rst = customFundPayMemberWriteService.deleteByCustomFundPayIdAndMemberId(customFundPayId, memberIdList);
        if(rst <= 0){
            throw new BizException("-1", "名册成员删除失败");
        }


        rst = customFundPayWriteService.updateSubMemberNum(customFundPayId, memberIdList.size());
        if(rst <= 0){
            throw new BizException("-1", "名册信息更新失败");
        }
        return 1;
    }


    @Override
    public Page queryAllInNoBank(SalvationObjectParam param, PageParam pageParam){
        return orderReadService.queryAllInNoBank(param,pageParam);
    }


    @Override
    public List<CustomFundDTO> queryCustomByAllMem(SalvationObjectParam param, UserAccountVo userAccountVo){
        QueryParamUtil.setBaseParamValue(param, userAccountVo);
        return orderReadService.queryCustomByAllMem(param);
    }


    @Override
    public int updateMemberFundNumber(CustomFundPayMemberDTO customFundPayMemberDTO) {

        int rst = customFundPayMemberWriteService.updateById(customFundPayMemberDTO);
        if(rst <= 0){
            throw new BizException("-1", "成员信息修改失败");
        }


        rst = customFundPayWriteService.updatePayTotal(customFundPayMemberDTO.getCustomFundPayId());
        if(rst <= 0){
            throw new BizException("-1", "成员信息修改失败");
        }
        return 1;
    }



    private String packageRstMsg(Map<String, CustomFundPayMemberDTO> allExcelMemberMap, List<CustomFundPayMemberEntity> addSuccessMemberList){
        if(allExcelMemberMap.size() == addSuccessMemberList.size()){

            return "导入成功";
        }
        List<String> addSuccessIdcardList = addSuccessMemberList.stream().map(CustomFundPayMemberEntity::getIdcard).collect(Collectors.toList());
        StringBuffer rstNames = new StringBuffer("导入成功，其中【");
        for(String idcard : allExcelMemberMap.keySet()){

            if(addSuccessIdcardList.contains(idcard) == false){
                rstNames.append(allExcelMemberMap.get(idcard).getName()).append("、");
            }
        }
        rstNames.deleteCharAt(rstNames.length() - 1).append("】用户信息未找到");
        return rstNames.toString();
    }


    @Override
    public ExcelInfo exportExcelFundPayMember(String exportType, List<String> orderIdList, SalvationObjectParam param, UserAccountVo userAccountVo){
        ExcelInfo excelInfo = null;
        if("1".equals(exportType)){

            List<CustomFundDTO> list = this.queryCustomByAllMem(param, userAccountVo);
            excelInfo = exportExcelService.exportOrgOpLogs(CustomFundDTO.class,list,"自定义补发人员信息.xls",
                    "自定义补发人员列表","自定义补发人员列表",false,"");
        }
        if(null != excelInfo){
            InputStream sbs = new ByteArrayInputStream(excelInfo.getFile());
            String objectkey = fileService.upload(sbs,excelInfo.getFileName());
            if(StringUtils.isNotBlank(objectkey)){
                TaskExportEntity taskExport = new TaskExportEntity();
                taskExport.setId(Constant.getUUID());
                taskExport.setUserid(userAccountVo.getUserId());
                taskExport.setTaskName(excelInfo.getFileName());
                taskExport.setTaskTitle("自定义补发人员列表");
                taskExport.setParam("xls");
                taskExport.setCreateTime(new Date());
                taskExport.setFileUrl(objectkey);
                taskExport.setState("02");
                int i = taskExportWriteService.insertIgnoreNull(taskExport);
                if(i > 0){
                    excelInfo = null;
                }
            }
        }
        return excelInfo;
    }

}
